package distrcomp;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;

import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;

public class AdminImpl extends UnicastRemoteObject implements Admin {
	private static final long serialVersionUID = 1L;
	private Server server;

	protected AdminImpl(Server server) throws RemoteException {
		super(0, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory(null, null, true));
		this.server = server;
	}

	public void setRate(ShippingType type, float rate) throws RemoteException {
		//Inform slaves of the new shipping rates
		HashMap<Integer, Subserver> subServers = server.getSubservers();
		Iterator<Entry<Integer, Subserver>> it = subServers.entrySet().iterator();
		while(it.hasNext()) {
			Map.Entry<Integer, Subserver> keyVal = (Map.Entry<Integer,Subserver>) it.next();
			((Subserver)keyVal.getValue()).setPrice(type, rate);
		}
		//Also keep the rates to inform new slaves
		this.server.setRate(type, rate);
	}
	
	public ShipmentIterator getPendingShipments() throws RemoteException {
		Vector<ShippingState> states = new Vector<ShippingState>();
		states.add(ShippingState.PENDING);
		return new ShipmentIteratorImpl(server, states);
	}
	
	public ShipmentIterator getShipmentHistory() throws RemoteException {
		Vector<ShippingState> states = new Vector<ShippingState>();
		states.add(ShippingState.IN_ROUTE);
		states.add(ShippingState.ARRIVED);
		return new ShipmentIteratorImpl(server, states);
	}

	public void setRates(float ground, float air, float air_pr)	throws RemoteException {
		//Inform slaves of the new shipping rates
		HashMap<Integer, Subserver> subServers = server.getSubservers();
		Iterator<Entry<Integer, Subserver>> it = subServers.entrySet().iterator();
		while(it.hasNext()) {
			Map.Entry<Integer, Subserver> keyVal = (Map.Entry<Integer,Subserver>) it.next();
			((Subserver)keyVal.getValue()).setPrices(ground, air, air_pr);
		}
		//Also keep the rates to inform new slaves
		this.server.setRates(ground, air, air_pr);
	}

	public boolean backup(int slaveKey) throws RemoteException {
		this.server.getSubservers().get(slaveKey).backup();
		return false;
	}
}
